/**********************************************************************
 * 
 *
 * @url: /services/apexrest/rest
 * @data:
 *  {
        {
        "data":{"objectName":"User","operationType":"1","data":[{}]}
   }
    }
*************************************************************************/
@RestResource(urlMapping='/CRM/upsertObjectREST/*')
global with sharing class UpsertObjectREST {
    @HttpPost
    global static RestReturnMessage upsertObject(String objectName ,string operationType,String datas,String keyword) {
    	RestReturnMessage message = null;
    	System.debug('==='+ objectName);
        try{
            if(objectName == null || operationType == null || datas == null ){
                 throw new DmlException('参数不确!');

            }else{
               	message = doUpsertObject(objectName,operationType,datas,keyword);
            }
        }
        catch(Exception e){
            System.debug(LoggingLevel.INFO, '*** 错误信息: ' + e.getMessage() );
            System.debug(LoggingLevel.INFO, '*** 错误跟踪: ' + e.getStackTraceString());
            message = Utils.getRestReturnMessage(false,e.getMessage() + ' - ' + e.getStackTraceString()+Datetime.valueOf(Utils.MIN_DATE_TIME),new List<Map<String ,String>>());
        }
        System.debug(LoggingLevel.INFO, '*** 调用返回信息: ' + message);
        return message;

    }

    global static RestReturnMessage doUpsertObject (String objectName ,string operationType,String datas,String keyword) {
    	RestReturnMessage message = null;

        Map<String,SObjectType> objMap = new Map<String,SObjectType>();
        ///获取所有对象
		for(Schema.sobjecttype s: Schema.getGlobalDescribe().values()){
                //选择自定义对象//&& s.getDescribe().isSearchable() == true
                if(s.getDescribe().IsCustom() == true || s.getDescribe().IsCustom() == false) {
                    //保存
                    objMap.put(s.getDescribe().getName(),s);
                }
		}
		///获取字段 及 字段的类型
		Map<String,String> fieldsMap = new Map<String,String>();
		if(objMap.containsKey(objectName)){
			SObjectType s = objMap.get(objectName);
			System.debug('==='+s);
			//获取传入对象的所有字段
        	for(Schema.SObjectField f :s.getDescribe().fields.getMap().values()){

        		fieldsMap.put(f.getDescribe().getName().toUpperCase(), f.getDescribe().getType()+'');
        	}
        	System.debug('==='+fieldsMap);
        	List<Object> os = null;
        	 List<SObject> ss = new List<SObject>();
        	try {
        		//System.debug(EncodingUtil.urlDecode(data,'UTF-8'));
        		System.debug('==='+JSON.deserializeUntyped(EncodingUtil.urlDecode(datas,'UTF-8')) );
        	    os = (List<Object>)JSON.deserializeUntyped(EncodingUtil.urlDecode(datas,'UTF-8')) ; 

	            Set<String> updateSet = new Set<String>(); 
	            Map<String ,String> keyMap = new Map<String ,String>();

	            if(operationType == '2' && keyword != null && keyword != '' ){
                    String tempKW = keyword.toUpperCase();
	            	if(!fieldsMap.containsKey(tempKW))return Utils.getRestReturnMessage(false,'该对象中不包含'+keyword +'字段!',new List<Map<String ,String>>());
	            	 for(Object o :os){
		       			Map<String ,Object> res = (Map<String ,Object> )o ;
		       			if(res.containsKey(keyword)){
		       				if(keyword != null&& res.get(keyword)!= null )updateSet.add(String.valueOf(res.get(keyword)) );
		       			}else{
		       				return Utils.getRestReturnMessage(false,'数据不正确中不包含'+keyword +'的数据!',new List<Map<String ,String>>());
		       			}
		       		}

		       		String ks = '';
                    Integer j = 0;
		            for(String k :updateSet){
		            	ks += '\''+k + '\',';
		            }
		            ks = ks.substring(0,ks.length() -1);

		            String sql = 'select Id ';
                    if(keyword.toUpperCase() != 'ID')sql += ' , ' +keyword ;
                    sql += ' from '+ objectName +' where ' + keyword +' in (' + ks +')';

                    System.debug(sql);
		            List<SObject> alList = Database.query(sql);

		            for(SObject o :alList){
		            	keyMap.put(String.valueOf(o.get(keyword)),String.valueOf(o.get('Id')));
		            }


	            }
	           
                System.debug(keyMap);
		       //按顺序匹配字段
		       for(Object o :os){
		       		 Map<String ,Object> res = (Map<String ,Object> )o ;

		       		 ///构建新的对象
		       		SObject row = s.newSobject();
		           	           ///解析每行数据

		       		for(String k : res.keySet() ){
                    
                      String  tempk =  k.toUpperCase();
		       		if(!fieldsMap.containsKey(tempk))return Utils.getRestReturnMessage(false,'对象不包含该字段:'+k,new List<Map<String ,String>>());
 		       			row.put(k,dataHandler(res.get(k) ,fieldsMap.get(tempk)));
		       		}
		       		if(operationType == '2' && keyword != null && keyword != ''){
                        System.debug(res.get(keyword));
                        row.put('Id',keyMap.get(String.valueOf(res.get(keyword))));
                    }
		           	ss.add(row);
		           	
		       }  
        	}catch (Exception e) {
        	 	  return Utils.getRestReturnMessage(false,e.getMessage(),new List<Map<String ,String>>());
        	}
        	
        	         

	       if(ss.size() > 0){
	       	SavePoint sp = Database.setSavePoint();
	       	try {
                System.debug(ss);
		       	    ///  1  新增   2  更新  
		       	if(operationType == '1')insert  ss;
		       	if(operationType == '2') update ss;
                message = Utils.getRestReturnMessage(true,'更新成功!',new List<Map<String ,String>>());
	       	}catch (Exception e) {
	       		Database.rollback(sp);
	       	    message = Utils.getRestReturnMessage(false,'数据保存失败:'+e.getMessage(),new List<Map<String ,String>>());
	       	}
	       	
	       	
	       }else{

	       		message = Utils.getRestReturnMessage(false,'没有数据!',new List<Map<String ,String>>());
	       }

		}else{
		  	message =  Utils.getRestReturnMessage(false,'传入对象名错误!',new List<Map<String ,String>>());
		}

    	return message;
    }

    ///处理数据: 根据数据的类型返回指定数据类型的数据
    global static Object dataHandler(object o, String type){
    	if(o == null){
    		return null;
    	}else if(type == 'CURRENCY' || type == 'DOUBLE' ||type == 'PERCENT'){
        //小数
            Decimal tmp = null;
            try {
              tmp =   Decimal.valueOf(String.valueOf(o).trim());
            }
            catch (Exception e) {
                
            }
            
            return tmp;
        }else if(type == 'INTEGER' ){
        //整数
            Integer tmp = null;
            try {
              tmp =  Integer.valueOf(String.valueOf(o).trim());
            }
            catch (Exception e) {
                
            }

           return tmp;
        }else if(type == 'DATE'){
        //日期
             Date tmp = null;
            try {
              tmp =  Date.valueOf(String.valueOf(o).trim());
            }
            catch (Exception e) {
                
            }
           return tmp ;
        }else if(type == 'BOOLEAN'){
        	return Boolean.valueOf(o);
        }else if(type == 'DATETIME'){
        //日期时间
             DateTime tmp = null;
            try {
              tmp =  DateTime.valueOf(String.valueOf(o).trim());
            }
            catch (Exception e) {
                
            }
           return tmp ;
        }else if(type == 'TIME'){
        //时间
           String t = (String) o;
           if(t.length() == 0) return null;
           List<String>ts = t.split(':',-1);
           if(ts.size() == 1) return Time.newInstance(Integer.valueOf(ts[0]),0,0,0);
           return ts.size() > 2 ? Time.newInstance(Integer.valueOf(ts[0]),Integer.valueOf(ts[1]),Integer.valueOf(ts[2]),0):Time.newInstance(Integer.valueOf(ts[0]),Integer.valueOf(ts[1]),0,0);
        }else {
        //字符串
        	return o;
        }
        
    }   

     global class ObjectRestArgs {
     	global String objectName ; ///对象名
     	global String operationType; /// 操作类型
     	global String keyword ;//更新匹配的键

     }
}